// 文件资源管理器组件

import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
  ChevronRight,
  ChevronDown,
  Search,
  Plus,
  FolderPlus,
  MoreHorizontal,
  RefreshCw as Refresh,
  X,
  Undo2 as Undo,
  Redo2 as Redo,
} from 'lucide-react';
import { FileItem, FileTreeNode, buildFileTree, matchesSearchQuery } from '../types/filesystem';
import { FileSystemService } from '../services/filesystem';
import { FileIcon, FileSizeIndicator, FileStatusIcon } from './FileIcon';
import { FileOperationDialog } from './FileOperationDialog';
import { AdvancedSearch } from './AdvancedSearch';
import { useFileSystemStore } from '../stores/fileSystemStore';
import { useDragAndDrop, useMultiSelect } from '../hooks/useDragAndDrop';
import { useFileStatus } from '../hooks/useFileStatus';

interface FileExplorerProps {
  workspacePath?: string;
  onFileSelect?: (file: FileItem) => void;
  onFileOpen?: (file: FileItem) => void;
  className?: string;
}

/**
 * 文件资源管理器组件
 */
export const FileExplorer: React.FC<FileExplorerProps> = ({
  workspacePath,
  onFileSelect,
  onFileOpen,
  className = '',
}) => {
  const [files, setFiles] = useState<FileItem[]>([]);
  const [fileTree, setFileTree] = useState<FileTreeNode[]>([]);
  const [expandedDirectories, setExpandedDirectories] = useState<Set<string>>(new Set());
  const [selectedFiles, setSelectedFiles] = useState<Set<string>>(new Set());
  const [searchQuery, setSearchQuery] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [contextMenu, setContextMenu] = useState<{
    x: number;
    y: number;
    file: FileItem;
  } | null>(null);
  const [operationDialog, setOperationDialog] = useState<{
    isOpen: boolean;
    operation: 'create-file' | 'create-folder' | 'rename' | 'delete';
    targetFile?: FileItem;
    parentPath?: string;
  }>({
    isOpen: false,
    operation: 'create-file',
  });
  const [showAdvancedSearch, setShowAdvancedSearch] = useState(false);
  const [searchResults, setSearchResults] = useState<FileItem[]>([]);

  const searchInputRef = useRef<HTMLInputElement>(null);

  // 使用文件系统 store
  const {
    currentWorkspace,
    fileTree: globalFileTree,
    isLoading: globalIsLoading,
    error: globalError,
    createFile,
    createDirectory,
    deleteFile,
    renameFile,
    moveFile,
    undo,
    redo,
    canUndo,
    canRedo
  } = useFileSystemStore();

  // 确定使用的工作区路径和数据源
  const effectiveWorkspacePath = workspacePath || currentWorkspace?.path;
  const shouldUseGlobalState = !workspacePath && currentWorkspace;

  // 确定显示的数据
  const displayFiles = shouldUseGlobalState ? (currentWorkspace?.files || []) : files;
  const displayFileTree = shouldUseGlobalState ? globalFileTree : fileTree;
  const displayIsLoading = shouldUseGlobalState ? globalIsLoading : isLoading;
  const displayError = shouldUseGlobalState ? globalError : error;

  // 文件状态管理
  const {
    getFileStatus,
    hasUnsavedChanges,
    getModifiedFiles,
    markFileAsModified,
    markFileAsAdded,
    markFileAsDeleted,
    clearFileStatus,
  } = useFileStatus({ workspacePath: effectiveWorkspacePath });

  // 拖拽功能
  const {
    dragState,
    handleDragStart,
    handleDragEnd,
    handleDragEnter,
    handleDragOver,
    handleDragLeave,
    handleDrop,
    canDrag,
    canDrop,
    getDragStyles,
    getDragIndicator,
  } = useDragAndDrop({
    onFileDrop: async (draggedFiles, targetPath) => {
      // 处理文件拖拽
      return true;
    },
    onFileMove: async (sourcePath, targetPath) => {
      return await moveFile(sourcePath, targetPath);
    },
  });

  // 批量选择功能
  const {
    selectedPaths,
    selectFile: selectFileMulti,
    clearSelection,
    selectAll,
    invertSelection,
    isSelected,
  } = useMultiSelect({
    onSelectionChange: (paths) => {
      setSelectedFiles(new Set(paths));
    },
  });

  // 加载目录内容
  const loadDirectory = useCallback(async (path: string) => {
    if (!path) return;

    setIsLoading(true);
    setError(null);

    try {
      const directoryFiles = await FileSystemService.readDirectory(path);
      setFiles(directoryFiles);
      
      // 构建文件树
      const tree = buildFileTree(directoryFiles, path);
      setFileTree(tree);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load directory');
      console.error('Failed to load directory:', err);
    } finally {
      setIsLoading(false);
    }
  }, []);

  // 初始化加载
  useEffect(() => {
    if (workspacePath) {
      // 如果有传入workspacePath，使用本地状态
      loadDirectory(workspacePath);
    } else if (currentWorkspace) {
      // 如果没有传入workspacePath但有全局工作区，使用全局状态
      setFiles(currentWorkspace.files);
      const tree = buildFileTree(currentWorkspace.files, currentWorkspace.path);
      setFileTree(tree);
      setIsLoading(false);
      setError(null);
    }
  }, [workspacePath, currentWorkspace, loadDirectory]);

  // 切换目录展开状态
  const toggleDirectory = useCallback(async (directory: FileTreeNode) => {
    if (!directory.is_directory) return;

    const newExpanded = new Set(expandedDirectories);
    
    if (expandedDirectories.has(directory.path)) {
      // 折叠目录
      newExpanded.delete(directory.path);
    } else {
      // 展开目录
      newExpanded.add(directory.path);
      
      // 如果子目录还没有加载，则加载
      if (!directory.children || directory.children.length === 0) {
        try {
          const subFiles = await FileSystemService.readDirectory(directory.path);
          const subTree = buildFileTree(subFiles, directory.path);
          
          // 更新文件树
          setFileTree(prevTree => {
            const updateNode = (nodes: FileTreeNode[]): FileTreeNode[] => {
              return nodes.map(node => {
                if (node.path === directory.path) {
                  return {
                    ...node,
                    children: subTree.map(child => ({
                      ...child,
                      level: node.level + 1,
                      parent: node,
                    })),
                  };
                }
                if (node.children) {
                  return {
                    ...node,
                    children: updateNode(node.children),
                  };
                }
                return node;
              });
            };
            return updateNode(prevTree);
          });
        } catch (err) {
          console.error('Failed to load subdirectory:', err);
        }
      }
    }
    
    setExpandedDirectories(newExpanded);
  }, [expandedDirectories]);

  // 选择文件
  const selectFile = useCallback((
    file: FileItem,
    isCtrlClick: boolean = false,
    isShiftClick: boolean = false
  ) => {
    selectFileMulti(file.path, isCtrlClick, isShiftClick, files);
    onFileSelect?.(file);
  }, [selectFileMulti, files, onFileSelect]);

  // 双击打开文件
  const handleDoubleClick = useCallback((file: FileItem) => {
    if (file.is_directory) {
      toggleDirectory(file as FileTreeNode);
    } else {
      onFileOpen?.(file);
    }
  }, [toggleDirectory, onFileOpen]);

  // 右键菜单
  const handleContextMenu = useCallback((e: React.MouseEvent, file: FileItem) => {
    e.preventDefault();
    setContextMenu({
      x: e.clientX,
      y: e.clientY,
      file,
    });
  }, []);

  // 关闭右键菜单
  const closeContextMenu = useCallback(() => {
    setContextMenu(null);
  }, []);

  // 搜索过滤
  const filteredTree = useCallback((nodes: FileTreeNode[]): FileTreeNode[] => {
    if (!searchQuery.trim()) return nodes;

    const filterNodes = (nodeList: FileTreeNode[]): FileTreeNode[] => {
      const filtered: FileTreeNode[] = [];

      for (const node of nodeList) {
        const matches = matchesSearchQuery(node, searchQuery);
        const hasMatchingChildren = node.children && filterNodes(node.children).length > 0;

        if (matches || hasMatchingChildren) {
          filtered.push({
            ...node,
            children: node.children ? filterNodes(node.children) : undefined,
          });
        }
      }

      return filtered;
    };

    return filterNodes(nodes);
  }, [searchQuery]);

  // 渲染文件树节点
  const renderTreeNode = useCallback((node: FileTreeNode): React.ReactNode => {
    const isExpanded = expandedDirectories.has(node.path);
    const nodeIsSelected = isSelected(node.path);
    const dragStyles = getDragStyles(node);
    const dragIndicator = getDragIndicator(node);

    return (
      <div key={node.path} className="select-none relative">
        {/* 拖拽指示器 */}
        {dragIndicator}

        {/* 文件/目录项 */}
        <div
          className={`
            flex items-center px-2 py-1 text-sm cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700
            ${nodeIsSelected ? 'bg-blue-100 dark:bg-blue-900/30 text-blue-900 dark:text-blue-100' : 'text-gray-700 dark:text-gray-300'}
            ${dragStyles}
          `}
          style={{ paddingLeft: `${node.level * 16 + 8}px` }}
          draggable={canDrag(node)}
          onClick={(e) => selectFile(node, e.ctrlKey || e.metaKey, e.shiftKey)}
          onDoubleClick={() => handleDoubleClick(node)}
          onContextMenu={(e) => handleContextMenu(e, node)}
          onDragStart={(e) => {
            const selectedFilesToDrag = selectedPaths.length > 0 && nodeIsSelected
              ? files.filter(f => selectedPaths.includes(f.path))
              : [node];
            handleDragStart(e, selectedFilesToDrag, { x: e.clientX, y: e.clientY });
          }}
          onDragEnd={handleDragEnd}
          onDragEnter={(e) => handleDragEnter(e, node)}
          onDragOver={(e) => handleDragOver(e, node)}
          onDragLeave={(e) => handleDragLeave(e, node)}
          onDrop={(e) => handleDrop(e, node)}
        >
          {/* 展开/折叠图标 */}
          {node.is_directory && (
            <button
              className="flex items-center justify-center w-4 h-4 mr-1 hover:bg-gray-200 dark:hover:bg-gray-600 rounded"
              onClick={(e) => {
                e.stopPropagation();
                toggleDirectory(node);
              }}
            >
              {isExpanded ? (
                <ChevronDown size={12} />
              ) : (
                <ChevronRight size={12} />
              )}
            </button>
          )}
          
          {/* 文件图标 */}
          <div className="flex items-center mr-2">
            <FileIcon 
              file={node} 
              isExpanded={isExpanded}
              size={16}
            />
          </div>
          
          {/* 文件名 */}
          <span className="flex-1 truncate">
            {node.name}
          </span>
          
          {/* 文件状态指示器 */}
          {(() => {
            const status = getFileStatus(node.path);
            if (status !== 'normal') {
              return (
                <FileStatusIcon
                  status={status as 'modified' | 'added' | 'deleted' | 'conflicted'}
                  size={12}
                  className="ml-1"
                />
              );
            }
            return null;
          })()}

          {/* 文件大小 */}
          {!node.is_directory && node.size && (
            <FileSizeIndicator
              size={node.size}
              className="ml-2"
            />
          )}
        </div>

        {/* 子目录 */}
        {node.is_directory && isExpanded && node.children && (
          <div>
            {node.children.map(child => renderTreeNode(child))}
          </div>
        )}
      </div>
    );
  }, [expandedDirectories, selectedFiles, selectFile, handleDoubleClick, handleContextMenu, toggleDirectory]);

  // 刷新目录
  const refreshDirectory = useCallback(() => {
    if (effectiveWorkspacePath) {
      if (shouldUseGlobalState) {
        // 如果使用全局状态，刷新全局状态
        // 这里可以调用全局的刷新方法，但目前简化处理
        console.log('Refresh global workspace');
      } else {
        loadDirectory(effectiveWorkspacePath);
      }
    }
  }, [effectiveWorkspacePath, shouldUseGlobalState, loadDirectory]);

  // 清除搜索
  const clearSearch = useCallback(() => {
    setSearchQuery('');
    searchInputRef.current?.focus();
  }, []);

  // 打开文件操作对话框
  const openOperationDialog = useCallback((
    operation: 'create-file' | 'create-folder' | 'rename' | 'delete',
    targetFile?: FileItem,
    parentPath?: string
  ) => {
    setOperationDialog({
      isOpen: true,
      operation,
      targetFile,
      parentPath: parentPath || effectiveWorkspacePath,
    });
    setContextMenu(null);
  }, [effectiveWorkspacePath]);

  // 关闭文件操作对话框
  const closeOperationDialog = useCallback(() => {
    setOperationDialog(prev => ({ ...prev, isOpen: false }));
  }, []);

  // 处理文件操作确认
  const handleOperationConfirm = useCallback(async (data: { name?: string; path?: string }) => {
    const { operation, targetFile } = operationDialog;

    try {
      let success = false;

      switch (operation) {
        case 'create-file':
          if (data.path) {
            success = await createFile(data.path);
            if (success) {
              markFileAsAdded(data.path);
            }
          }
          break;
        case 'create-folder':
          if (data.path) {
            success = await createDirectory(data.path);
            if (success) {
              markFileAsAdded(data.path);
            }
          }
          break;
        case 'rename':
          if (targetFile && data.name) {
            const parentDir = targetFile.path.substring(0, targetFile.path.lastIndexOf('/'));
            const newPath = `${parentDir}/${data.name}`;
            success = await renameFile(targetFile.path, newPath);
            if (success) {
              clearFileStatus(targetFile.path);
              markFileAsModified(newPath);
            }
          }
          break;
        case 'delete':
          if (targetFile) {
            success = await deleteFile(targetFile.path);
            if (success) {
              markFileAsDeleted(targetFile.path);
            }
          }
          break;
      }

      if (success) {
        // 刷新目录
        if (effectiveWorkspacePath) {
          await loadDirectory(effectiveWorkspacePath);
        }
      }

      return success;
    } catch (error) {
      console.error('File operation failed:', error);
      return false;
    }
  }, [operationDialog, createFile, createDirectory, renameFile, deleteFile, loadDirectory, effectiveWorkspacePath]);

  // 工具栏按钮处理
  const handleNewFile = useCallback(() => {
    openOperationDialog('create-file', undefined, effectiveWorkspacePath);
  }, [openOperationDialog, effectiveWorkspacePath]);

  const handleNewFolder = useCallback(() => {
    openOperationDialog('create-folder', undefined, effectiveWorkspacePath);
  }, [openOperationDialog, effectiveWorkspacePath]);

  // 处理搜索结果
  const handleSearchResults = useCallback((results: FileItem[]) => {
    setSearchResults(results);
  }, []);

  // 切换高级搜索
  const toggleAdvancedSearch = useCallback(() => {
    setShowAdvancedSearch(!showAdvancedSearch);
    if (showAdvancedSearch) {
      setSearchResults([]);
      setSearchQuery('');
    }
  }, [showAdvancedSearch]);

  // 关闭高级搜索
  const closeAdvancedSearch = useCallback(() => {
    setShowAdvancedSearch(false);
    setSearchResults([]);
    setSearchQuery('');
  }, []);

  // 显示的文件列表：搜索结果或过滤后的文件树
  const displayTree = searchResults.length > 0
    ? buildFileTree(searchResults, effectiveWorkspacePath || '')
    : filteredTree(displayFileTree);

  return (
    <div className={`flex flex-col h-full bg-white dark:bg-gray-800 ${className}`}>
      {/* 工具栏 */}
      <div className="flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-700">
        <h3 className="text-sm font-medium text-gray-700 dark:text-gray-300">
          文件资源管理器
        </h3>
        <div className="flex items-center space-x-1">
          <button
            className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
            onClick={refreshDirectory}
            title="刷新"
          >
            <Refresh size={14} />
          </button>
          <div className="w-px h-4 bg-gray-300 dark:bg-gray-600 mx-1" />
          <button
            className={`p-1 rounded ${
              canUndo()
                ? 'hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300'
                : 'text-gray-400 dark:text-gray-600 cursor-not-allowed'
            }`}
            onClick={() => canUndo() && undo()}
            disabled={!canUndo()}
            title="撤销"
          >
            <Undo size={14} />
          </button>
          <button
            className={`p-1 rounded ${
              canRedo()
                ? 'hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300'
                : 'text-gray-400 dark:text-gray-600 cursor-not-allowed'
            }`}
            onClick={() => canRedo() && redo()}
            disabled={!canRedo()}
            title="重做"
          >
            <Redo size={14} />
          </button>
          <button
            className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
            onClick={handleNewFile}
            title="新建文件"
          >
            <Plus size={14} />
          </button>
          <button
            className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
            onClick={handleNewFolder}
            title="新建文件夹"
          >
            <FolderPlus size={14} />
          </button>
          <div className="relative">
            <button
              className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
              title="更多操作"
              onClick={() => {
                // TODO: 实现下拉菜单
              }}
            >
              <MoreHorizontal size={14} />
            </button>
          </div>
        </div>
      </div>

      {/* 搜索框 */}
      <div className="p-2 border-b border-gray-200 dark:border-gray-700">
        <div className="relative">
          <Search
            size={14}
            className="absolute left-2 top-1/2 transform -translate-y-1/2 text-gray-400"
          />
          <input
            ref={searchInputRef}
            type="text"
            placeholder="搜索文件..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            onFocus={toggleAdvancedSearch}
            className="w-full pl-8 pr-8 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500"
          />
          {searchQuery && (
            <button
              onClick={clearSearch}
              className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600"
            >
              <X size={14} />
            </button>
          )}
        </div>

        {/* 选择状态显示 */}
        {selectedPaths.length > 0 && (
          <div className="mt-2 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
            <span>已选择 {selectedPaths.length} 个项目</span>
            <div className="flex items-center space-x-2">
              <button
                onClick={() => selectAll(files)}
                className="hover:text-gray-700 dark:hover:text-gray-300"
              >
                全选
              </button>
              <button
                onClick={clearSelection}
                className="hover:text-gray-700 dark:hover:text-gray-300"
              >
                清除
              </button>
            </div>
          </div>
        )}

        {/* 文件状态统计 */}
        {(() => {
          const modifiedFiles = getModifiedFiles();
          if (modifiedFiles.length > 0) {
            return (
              <div className="mt-2 text-xs text-orange-600 dark:text-orange-400">
                {modifiedFiles.length} 个文件已修改
              </div>
            );
          }
          return null;
        })()}
      </div>

      {/* 文件树 */}
      <div className="flex-1 overflow-auto">
        {displayIsLoading ? (
          <div className="flex items-center justify-center p-4">
            <div className="text-sm text-gray-500">加载中...</div>
          </div>
        ) : displayError ? (
          <div className="flex items-center justify-center p-4">
            <div className="text-sm text-red-500">{displayError}</div>
          </div>
        ) : displayTree.length === 0 ? (
          <div className="flex items-center justify-center p-4">
            <div className="text-sm text-gray-500">
              {searchQuery ? '没有找到匹配的文件' : '目录为空'}
            </div>
          </div>
        ) : (
          <div className="py-1">
            {displayTree.map(node => renderTreeNode(node))}
          </div>
        )}
      </div>

      {/* 右键菜单 */}
      {contextMenu && (
        <>
          <div
            className="fixed inset-0 z-40"
            onClick={closeContextMenu}
          />
          <div
            className="fixed z-50 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg py-1 min-w-[120px]"
            style={{
              left: contextMenu.x,
              top: contextMenu.y,
            }}
          >
            <button
              className="w-full px-3 py-1.5 text-left text-sm hover:bg-gray-100 dark:hover:bg-gray-700"
              onClick={() => handleDoubleClick(contextMenu.file)}
            >
              打开
            </button>
            <button
              className="w-full px-3 py-1.5 text-left text-sm hover:bg-gray-100 dark:hover:bg-gray-700"
              onClick={() => openOperationDialog('rename', contextMenu.file)}
            >
              重命名
            </button>
            <button
              className="w-full px-3 py-1.5 text-left text-sm hover:bg-gray-100 dark:hover:bg-gray-700"
              onClick={() => {
                navigator.clipboard.writeText(contextMenu.file.path);
                setContextMenu(null);
              }}
            >
              复制路径
            </button>
            <hr className="my-1 border-gray-200 dark:border-gray-700" />
            <button
              className="w-full px-3 py-1.5 text-left text-sm text-red-600 hover:bg-gray-100 dark:hover:bg-gray-700"
              onClick={() => openOperationDialog('delete', contextMenu.file)}
            >
              删除
            </button>
          </div>
        </>
      )}

      {/* 文件操作对话框 */}
      <FileOperationDialog
        isOpen={operationDialog.isOpen}
        operation={operationDialog.operation}
        targetFile={operationDialog.targetFile}
        parentPath={operationDialog.parentPath}
        onClose={closeOperationDialog}
        onConfirm={handleOperationConfirm}
      />

      {/* 高级搜索 */}
      {showAdvancedSearch && (
        <div className="absolute inset-0 z-50 bg-black bg-opacity-50 flex items-center justify-center p-4">
          <div className="w-full max-w-2xl max-h-[80vh] overflow-auto">
            <AdvancedSearch
              workspacePath={effectiveWorkspacePath}
              onSearchResults={handleSearchResults}
              onClose={closeAdvancedSearch}
            />
          </div>
        </div>
      )}
    </div>
  );
};
